/* EIX - IPC system
 * Copyright (C) 2008-2011 Jorge Luis Zapata
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 * If not, see <http://www.gnu.org/licenses/>.
 */
#include "Eix.h"
#include "eix_private.h"
/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
static Eina_Hash *_messages;
static Ender_Namespace *_ns = NULL;
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/
void eix_message_init(void)
{
	Ender_Descriptor *d;
	Ender_Container *c;
	Ender_Property *p;

	_messages = eina_hash_int32_new(NULL);
	/* register the error message */
	_ns = ender_namespace_new("Eix", 0);
	if (!_ns) return;

	d = ender_namespace_descriptor_add(
			_ns,
			"Error",
			NULL,
			NULL,
			NULL,
			ENDER_TYPE_STRUCT, sizeof(Eix_Error));
	c = ender_container_new(ENDER_INT32);
	p = ender_descriptor_property_add(d, "code",
			c,
			NULL,
			NULL,
			NULL,
			NULL,
			NULL,
			NULL,
			EINA_FALSE, offsetof(Eix_Error, code));
	c = ender_container_new(ENDER_STRING);
	p = ender_descriptor_property_add(d, "msg",
			c,
			NULL,
			NULL,
			NULL,
			NULL,
			NULL,
			NULL,
			EINA_FALSE, offsetof(Eix_Error, msg));
	EIX_MESSAGE_ERROR = eix_message_add(d, NULL, 0);
}

void eix_message_shutdown(void)
{
	/* TODO free the hash */
}

Eix_Message * eix_message_find(int id)
{
	Eix_Message *thiz;

	thiz = eina_hash_find(_messages, (const void *)&id);
	return thiz;
}

/*============================================================================*
 *                                   API                                      *
 *============================================================================*/
Eix_Message *EIX_MESSAGE_ERROR = NULL;

EAPI Eix_Message * eix_message_add(Ender_Descriptor *d, Eix_Message *reply,
		double timeout)
{
	Eix_Message *thiz;
	static int id = 0;

	if (reply && reply->reply)
	{
		ERR("Can not create a message with the reply %d as it also "
				" needs a reply", reply->id);
		return NULL;
	}

	thiz = calloc(1, sizeof(Eix_Message));
	thiz->id = id++;
	thiz->reply = reply;
	thiz->edd = d;
	thiz->timeout = timeout;
	if (!thiz->reply)
	{
		thiz->type = EIX_MESSAGE_SIGNAL;
	}
	else
	{
		/* async reply */
		if (timeout < 0)
			thiz->type = EIX_MESSAGE_REPLY_ASYNC;
		else
			thiz->type = EIX_MESSAGE_REPLY_SYNC;
	}
	eina_hash_add(_messages, (const void *)&thiz->id, thiz);

	return thiz;
}

EAPI Eix_Message * eix_message_reply_get(Eix_Message *thiz)
{
	if (!thiz) return NULL;
	return thiz->reply;
}
